package com.dcoinpay.sys.controller;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dcoinpay.common.aop.annotation.LogAnnotation;
import com.dcoinpay.common.exception.BusinessException;
import com.dcoinpay.common.exception.code.BaseResponseCode;
import com.dcoinpay.common.utils.DataResult;
import com.dcoinpay.sys.entity.SysUser;
import com.dcoinpay.sys.entity.SysUserRole;
import com.dcoinpay.sys.service.HttpSessionService;
import com.dcoinpay.sys.service.UserRoleService;
import com.dcoinpay.sys.service.UserService;
import com.dcoinpay.sys.vo.req.LoginReqVO;
import com.dcoinpay.sys.vo.req.RegisterReqVO;
import com.dcoinpay.sys.vo.req.UpdatePasswordReqVO;
import com.dcoinpay.sys.vo.req.UserRoleOperationReqVO;
import com.dcoinpay.sys.vo.resp.LoginRespVO;
import com.dcoinpay.sys.vo.resp.UserOwnRoleRespVO;
import com.google.code.kaptcha.Constants;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 用户管理
 *
 * @author wenbin
 * @version V1.0
 * @date 2020年3月18日
 */
@RestController
@Api(tags = "组织模块-用户管理")
@RequestMapping("/sys")
public class UserController {
	@Autowired
	private UserService userService;
	@Autowired
	private UserRoleService userRoleService;
	@Autowired
	private HttpSessionService httpSessionService;

	/**
	 * 跳转到页面
	 */
	@GetMapping("/user/listview")
	public ModelAndView listview() {
		return new ModelAndView("sys/user/list");
	}

	@PostMapping(value = "/user/login")
	@ApiOperation(value = "用户登录接口")
	public DataResult<LoginRespVO> login(HttpServletRequest request, HttpServletResponse response, @RequestBody @Valid LoginReqVO vo) {
		//校验图像验证码
		validImageCode(vo.getCaptcha(), request);
		DataResult<LoginRespVO> result = DataResult.success();
		LoginRespVO loginRespVO = userService.login(vo);
		result.setData(loginRespVO);
		Subject subject = SecurityUtils.getSubject();
		UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginRespVO.getAccessToken(), loginRespVO.getAccessToken());
		subject.login(usernamePasswordToken);
//		WebUtils.addCookie(request, response, Constant.ACCESS_TOKEN, result.getData().getAccessToken());
		return result;
	}

	@PostMapping("/user/register")
	@ApiOperation(value = "用户注册接口")
	public DataResult<String> register(@RequestBody @Valid RegisterReqVO vo) {
		DataResult<String> result = DataResult.success();
		result.setData(userService.register(vo));
		return result;
	}

	@GetMapping("/user/unLogin")
	@ApiOperation(value = "引导客户端去登录")
	public DataResult<Object> unLogin() {
		DataResult<Object> result = DataResult.getResult(BaseResponseCode.TOKEN_ERROR);
		return result;
	}

	@PutMapping("/user")
	@ApiOperation(value = "更新用户信息接口")
	@LogAnnotation(title = "用户管理", action = "更新用户信息")
	@RequiresPermissions("sys:user:update")
	public DataResult<Object> updateUserInfo(@RequestBody SysUser vo) {
		if (StringUtils.isEmpty(vo.getId())) {
			return DataResult.fail("id不能为空");
		}
		String userId = httpSessionService.getCurrentUserId();
		userService.updateUserInfo(vo, userId);
		return DataResult.success();
	}

	@PutMapping("/user/info")
	@ApiOperation(value = "更新用户信息接口")
	@LogAnnotation(title = "用户管理", action = "更新用户信息")
	public DataResult<Object> updateUserInfoById(@RequestBody SysUser vo, HttpServletRequest request) {
		String userId = httpSessionService.getCurrentUserId();
		vo.setId(userId);
		userService.updateUserInfoMy(vo, userId);
		return DataResult.success();
	}

	@GetMapping("/user/{id}")
	@ApiOperation(value = "查询用户详情接口")
	@LogAnnotation(title = "用户管理", action = "查询用户详情")
	@RequiresPermissions("sys:user:detail")
	public DataResult<SysUser> detailInfo(@PathVariable("id") String id) {
		DataResult<SysUser> result = DataResult.success();
		result.setData(userService.detailInfo(id));
		return result;
	}

	@GetMapping("/user")
	@ApiOperation(value = "查询用户详情接口")
	@LogAnnotation(title = "用户管理", action = "查询用户详情")
	public DataResult<SysUser> youSelfInfo(HttpServletRequest request) {
		String userId = httpSessionService.getCurrentUserId();
		DataResult<SysUser> result = DataResult.success();
		result.setData(userService.detailInfo(userId));
		return result;
	}

	@PostMapping("/users")
	@ApiOperation(value = "分页获取用户列表接口")
	@RequiresPermissions("sys:user:list")
	@LogAnnotation(title = "用户管理", action = "分页获取用户列表")
	public DataResult<IPage<SysUser>> pageInfo(@RequestBody SysUser vo) {
		return DataResult.success(userService.pageInfo(vo));
	}

	@PostMapping("/user")
	@ApiOperation(value = "新增用户接口")
	@RequiresPermissions("sys:user:add")
	@LogAnnotation(title = "用户管理", action = "新增用户")
	public DataResult<Object> addUser(@RequestBody @Valid SysUser vo) {
		userService.addUser(vo);
		return DataResult.success();
	}

	@GetMapping("/user/logout")
	@ApiOperation(value = "退出接口")
	@LogAnnotation(title = "用户管理", action = "退出")
	public DataResult<Object> logout(HttpServletRequest request) {
		userService.logout();
		return DataResult.success();
	}

	@PutMapping("/user/pwd")
	@ApiOperation(value = "修改密码接口")
	@LogAnnotation(title = "用户管理", action = "更新密码")
	public DataResult<Object> updatePwd(@RequestBody UpdatePasswordReqVO vo, HttpServletRequest request) {
		String userId = httpSessionService.getCurrentUserId();
		userService.updatePwd(vo, userId);
		return DataResult.success();
	}

	@DeleteMapping("/user")
	@ApiOperation(value = "删除用户接口")
	@LogAnnotation(title = "用户管理", action = "删除用户")
	@RequiresPermissions("sys:user:deleted")
	public DataResult<Object> deletedUser(@RequestBody @ApiParam(value = "用户id集合") List<String> userIds, HttpServletRequest request) {
		//删除用户， 删除redis的绑定的角色跟权限
		httpSessionService.abortUserByUserIds(userIds);
		LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<SysUser>();
		queryWrapper.in(SysUser::getId, userIds);
		userService.remove(queryWrapper);
		return DataResult.success();
	}

	@GetMapping("/user/roles/{userId}")
	@ApiOperation(value = "赋予角色-获取所有角色接口")
	@LogAnnotation(title = "用户管理", action = "赋予角色-获取所有角色接口")
	@RequiresPermissions("sys:user:role:detail")
	public DataResult<UserOwnRoleRespVO> getUserOwnRole(@PathVariable("userId") String userId) {
		DataResult<UserOwnRoleRespVO> result = DataResult.success();
		result.setData(userService.getUserOwnRole(userId));
		return result;
	}

	@PutMapping("/user/roles/{userId}")
	@ApiOperation(value = "赋予角色-用户赋予角色接口")
	@LogAnnotation(title = "用户管理", action = "赋予角色-用户赋予角色接口")
	@RequiresPermissions("sys:user:update:role")
	public DataResult<UserOwnRoleRespVO> setUserOwnRole(@PathVariable("userId") String userId, @RequestBody List<String> roleIds) {

		LambdaQueryWrapper<SysUserRole> queryWrapper = new LambdaQueryWrapper<SysUserRole>();
		queryWrapper.eq(SysUserRole::getUserId, userId);
		userRoleService.remove(queryWrapper);
		if (null != roleIds && !roleIds.isEmpty()) {
			UserRoleOperationReqVO reqVO = new UserRoleOperationReqVO();
			reqVO.setUserId(userId);
			reqVO.setRoleIds(roleIds);
			userRoleService.addUserRoleInfo(reqVO);
		}
		httpSessionService.refreshUerId(userId);
		return DataResult.success();
	}

	/**
	 * 校验图像验证码
	 * 
	 * @param imageCode 验证码
	 * @param request request
	 */
	private void validImageCode(String imageCode, HttpServletRequest request) {
		String captchaId = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
		if (!captchaId.equals(imageCode)) {
			throw new BusinessException("验证码输入有误");
		}
	}

}
